﻿using Cms.Application.Admin.Views;
using Cms.Data;
using Cms.Domain;
using Cms.Domain.RepositoryInterfaces;

namespace Cms.Application.Admin.Presenters
{
    public class EditMenuItemPresenter : BasePresenter
    {
        private readonly Administrator _administrator;
        private readonly IEditMenuItemView _view;

        public EditMenuItemPresenter(IEditMenuItemView view)
            : this(view, new RepositoryFactory())
        {
        }
        
        public EditMenuItemPresenter(IEditMenuItemView view, IRepositoryFactory repositoryFactory)
            : base(view, repositoryFactory)
        {
            _view = view;
            _administrator = AdministratorRepository.GetAdministrator(_view.AdministratorID);
            if (!_administrator.HasPermission.EditMenuItem)
                _view.RedirectToPermissionDeniedPage();
        }
        
        public void SetLocales()
        {
            _view.SetLocales(_administrator.CurrentSite.Locales);
        }
        
        public void Initialize()
        {
            Menu menu = SiteRepository.GetMenu(_view.MenuID, _administrator.CurrentSite.ID);
            MenuVersion version = menu.GetVersion(_view.VersionID);
            _view.SelectedLocaleID = _view.LocaleID;
            _view.SetParentMenuItems(menu.Name, version.GetRootItems());
            _view.SetFolders(menu.Site.Domain, menu.Site.GetRootFolders());
            _view.SetPages(menu.Site.GetRootPages());
            _view.SetCategories(menu.Site.GetRootCategories());
            if (_view.MenuItemID == -1)
            {
                _view.SelectedParentMenuItemID = -1;
                _view.LinkTypes = MenuItemLinkType.Page;
                _view.Target = "self";
                _view.SetDefaultImage(null);
                _view.SetActiveImage(null);
                _view.SetDefaultHoverImage(null);
                _view.SetActiveHoverImage(null);
                _view.SelectedCategoryID = -1;
                UpdatePages();
            }
            else
            {
                MenuItem menuItem = version.GetItem(_view.MenuItemID);
                MenuItemTranslation translation = menuItem.GetTranslation(_view.SelectedLocaleID);
                _view.Name = translation.Name;
                _view.SetDefaultImage(translation.DefaultImage);
                _view.SetActiveImage(translation.ActiveImage);
                _view.SetDefaultHoverImage(translation.DefaultHoverImage);
                _view.SetActiveHoverImage(translation.ActiveHoverImage);
                _view.SelectedCategoryID = menuItem.ActiveForPagesInCategory != null
                                               ? menuItem.ActiveForPagesInCategory.ID
                                               : -1;
                if (menuItem.Parent == null)
                    _view.SelectedParentMenuItemID = -1;
                else
                    _view.SelectedParentMenuItemID = menuItem.Parent.ID;
                _view.LinkTypes = menuItem.LinkType;
                if (menuItem.LinkType == MenuItemLinkType.Page && menuItem.Page != null)
                {
                    if (menuItem.Page.Folder == null)
                    {
                        _view.SelectedFolderID = -1;
                        //_view.SetPages(menu.Site.GetRootPages());
                    }
                    else
                    {
                        _view.SelectedFolderID = menuItem.Page.Folder.ID;
                        _view.SetPages(menuItem.Page.Folder.Pages);
                    }
                    _view.SelectedPageID = menuItem.Page.ID;
                }
                else if (menuItem.LinkType == MenuItemLinkType.Url)
                    _view.Url = translation.Url;
                _view.Target = string.IsNullOrEmpty(menuItem.Target) ? "self" : "blank";
            }
        }
        
        public void UpdateImage(string target, int mediaFileID)
        {
            MediaFile image = MediaRepository.GetMediaFile(mediaFileID);
            switch (target)
            {
                case "defaultimage":
                    _view.SetDefaultImage(image);
                    break;
                case "activeimage":
                    _view.SetActiveImage(image);
                    break;
                case "defaulthoverimage":
                    _view.SetDefaultHoverImage(image);
                    break;
                case "activehoverimage":
                    _view.SetActiveHoverImage(image);
                    break;
            }
        }
        
        public void UpdatePages()
        {
            _view.SetPages(_view.SelectedFolderID == -1
                               ? _administrator.CurrentSite.GetRootPages()
                               : FolderRepository.GetFolder(_view.SelectedFolderID).Pages);
        }
        
        public void Save()
        {
            Menu menu = SiteRepository.GetMenu(_view.MenuID, _administrator.CurrentSite.ID);
            MenuVersion version = menu.GetVersion(_view.VersionID);
            if (_view.Name.Trim() == "")
                AddValidationError(GetText(_view, "NoNameError"));
            if (_view.MenuItemID > 0 && _view.SelectedParentMenuItemID == _view.MenuItemID)
                AddValidationError(GetText(_view, "SaveInSelfError"));
            if (_view.MenuItemID > 0)
            {
                MenuItem editedMenuItem = version.GetItem(_view.MenuItemID);
                MenuItem selectedParentMenuItem = version.GetItem(_view.SelectedParentMenuItemID);
                if (editedMenuItem.IsParentTo(selectedParentMenuItem))
                    AddValidationError(GetText(_view, "SaveInChildError"));
            }
            if (
                !version.CanItemBeNamedAndMovedTo(_view.MenuItemID, _view.SelectedLocaleID, _view.Name,
                                                  version.GetItem(_view.SelectedParentMenuItemID)))
                AddValidationError(GetText(_view, "NameCollisionError"));
            if (_view.LinkTypes == MenuItemLinkType.Page && _view.SelectedPageID == -1)
                AddValidationError(GetText(_view, "NoPageError"));
            if (_view.LinkTypes == MenuItemLinkType.Url && _view.Url == "")
                AddValidationError(GetText(_view, "NoUrlError"));
            if (!IsValid)
                return;
            MenuItem item;
            MenuItem originalParent = null;
            if (_view.MenuItemID == -1)
            {
                item = new MenuItem { Version = version };
                version.Items.Add(item);
            }
            else
            {
                item = version.GetItem(_view.MenuItemID);
                originalParent = item.Parent;
            }
            MenuItemTranslation translation;
            if (item.Translations.ContainsKey(_view.SelectedLocaleID))
            {
                translation = item.Translations[_view.SelectedLocaleID];
            }
            else
            {
                translation = new MenuItemTranslation();
                item.Translations.Add(_view.SelectedLocaleID, translation);
            }
            translation.Name = _view.Name;
            translation.Url = _view.LinkTypes == MenuItemLinkType.Url ? _view.Url : null;
            translation.DefaultImage = MediaRepository.GetMediaFile(_view.SelectedDefaultImageID);
            translation.ActiveImage = MediaRepository.GetMediaFile(_view.SelectedActiveImageID);
            translation.DefaultHoverImage = MediaRepository.GetMediaFile(_view.SelectedDefaultHoverImageID);
            translation.ActiveHoverImage = MediaRepository.GetMediaFile(_view.SelectedActiveHoverImageID);
            item.Parent = version.GetItem(_view.SelectedParentMenuItemID);
            if (_view.MenuItemID == -1)
            {
                if (item.Parent != null)
                    item.Parent.SubItems.Add(item);
            }
            else
            {
                if (item.Parent == null & originalParent != null ||
                    item.Parent != null & originalParent == null ||
                    (item.Parent != null & originalParent != null && item.Parent.ID != originalParent.ID))
                {
                    if (originalParent != null)
                        originalParent.SubItems.Remove(item);
                    if (item.Parent != null)
                        item.Parent.SubItems.Add(item);
                }
            }
            item.LinkType = _view.LinkTypes;
            item.Target = _view.Target == "self" ? null : "blank";
            item.Page = _view.LinkTypes == MenuItemLinkType.Page ? PageRepository.GetPage(_view.SelectedPageID) : null;
            item.ActiveForPagesInCategory = PageRepository.GetCategory(_view.SelectedCategoryID);
            version.UpdateSortIndexes();
            SiteRepository.SaveMenu(menu);
        }
    }
}